﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;

namespace LiveLinq.Internal
{
	abstract class ObservableCollectionQueryResultBase<T> : QueryResultBase<T>, INotifyPropertyChanged, INotifyCollectionChanged, IEnumerable<T>, IList<T>
	{
		protected const string CountName = "Count";
		protected const string IndexerName = "Item[]";
		protected static PropertyChangedEventArgs _pcCount = new PropertyChangedEventArgs(CountName);
		protected static PropertyChangedEventArgs _pcIndexer = new PropertyChangedEventArgs(IndexerName);
		protected readonly List<T> Items = new List<T>();

		protected ObservableCollectionQueryResultBase(IEnumerable<T> source) : base(source) {}

		#region IEnumerable<T> Members

		public IEnumerator<T> GetEnumerator()
		{
			return Items.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}

		#endregion

		#region IList<T> Members

		T IList<T>.this[int index]
		{
			get { return Items[index]; }
			set { throw new NotSupportedException(); }
		}

		int ICollection<T>.Count
		{
			get { return Items.Count; }
		}

		bool ICollection<T>.IsReadOnly
		{
			get { return true; }
		}

		int IList<T>.IndexOf(T item)
		{
			return Items.IndexOf(item);
		}

		void IList<T>.Insert(int index, T item)
		{
			throw new NotSupportedException();
		}

		void IList<T>.RemoveAt(int index)
		{
			throw new NotSupportedException();
		}

		void ICollection<T>.Add(T item)
		{
			throw new NotSupportedException();
		}

		void ICollection<T>.Clear()
		{
			throw new NotSupportedException();
		}

		bool ICollection<T>.Contains(T item)
		{
			return Items.Contains(item);
		}

		void ICollection<T>.CopyTo(T[] array, int arrayIndex)
		{
			Items.CopyTo(array, arrayIndex);
		}

		bool ICollection<T>.Remove(T item)
		{
			throw new NotSupportedException();
		}

		#endregion

		#region INotifyCollectionChanged Members

		public event NotifyCollectionChangedEventHandler CollectionChanged = delegate { };

		#endregion

		#region INotifyPropertyChanged Members

		public event PropertyChangedEventHandler PropertyChanged = delegate { };

		#endregion

		protected void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
		{
			CollectionChanged(this, e);
		}

		protected void OnPropertyChanged(string name)
		{
			OnPropertyChanged(new PropertyChangedEventArgs(name));
		}

		protected void OnPropertyChanged(PropertyChangedEventArgs e)
		{
			PropertyChanged(this, e);
		}
	}
}